package com.tarena.luban.demo.gateway.filters;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.net.URI;
import java.util.List;

//@Component
public class MyFilterOne implements GlobalFilter, Ordered {
    /**
     * 网关过滤器的核心方法
     * @param exchange 交换机(http协议 两端数据的交换) 包含着2个重要对象 request response
     * @param chain
     * @return Mono spring webflux 框架的类型,像springmvc框架 视图解析对象,网关封装了底层spring webflux
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 检查过滤逻辑这个方法是否生效
        System.out.println("myFilterOne 生效了");
        ServerHttpRequest request = exchange.getRequest();
        // 1. 获取路径path
        RequestPath path = request.getPath();
        // http://localhost:20000/stock/abc path=?
        System.out.println("当前请求获取path:"+path);
        //2. 获取一个完整的http请求地址uri uri=http://localhost:20000/stock/abc http://localhost:20000/abc
        URI uri = request.getURI();
        System.out.println("当前请求的uri:"+uri);
        //3. 请求参数 http://localhost:20000/stock/abc?name=wanglaoshi&name=liulaoshi
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        // 从参数对象拿到name值age值 key 就是map的key值 但是value封装了一个list
        List<String> names = queryParams.get("name");
        System.out.println("当前请求参数names:"+names);
        String name = queryParams.getFirst("name");
        System.out.println("当前请求参数name:"+name);
        //4. 获取请求头 Headers Host 如果网关实现的jwt统一解析 Authorization
        HttpHeaders headers = request.getHeaders();
        List<String> host = headers.get("Host");
        System.out.println("当前请求的host头:"+host.get(0));
        //5.获取cookie
        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
        if (ObjectUtils.isNotEmpty(cookies)) {
            HttpCookie first = cookies.getFirst("Idea-fc757afb");
            System.out.println("当前请求cookie:"+first);
        }
        //6.一般服务器可以通过请求 获取客户端的ip地址信息 remote
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        System.out.println("当前请求的客户端地址:"+remoteAddress.getHostName());
        //正常的过滤器返回值
        Mono<Void> mono = chain.filter(exchange);
        //TODO 处理错误 异常的mono返回值
        return mono;
    }

    /**
     * 过滤器排序的方法
     * @return Integer.MIN_VALUE~Integer_MAX_VALUE 数字越小,排序执行顺序越靠前
     * 如果数字相同的,按照默认排序规则
     * 有意思的问题: 最小整数二进制 是多少 最大正整数二进制是什么
     */
    @Override
    public int getOrder() {
        return -2000;
    }
}
